package com.atguigu.gmall.product.service.impl;

import com.atguigu.gmall.model.list.SearchAttr;
import com.atguigu.gmall.model.product.*;
import com.atguigu.gmall.product.domain.BaseCategoryView;
import com.atguigu.gmall.product.mapper.BaseCategoryViewMapper;
import com.atguigu.gmall.product.mapper.BaseTrademarkMapper;
import com.atguigu.gmall.product.mapper.SkuAttrValueMapper;
import com.google.common.collect.Lists;

import java.util.Date;

import com.atguigu.gmall.common.constans.RedisConstant;
import com.atguigu.gmall.common.util.JsonUtil;
import com.atguigu.gmall.feign.list.ListFeignClient;
import com.atguigu.gmall.model.list.Goods;
import com.atguigu.gmall.product.dto.ValueJsonDto;
import com.atguigu.gmall.product.service.SkuAttrValueService;
import com.atguigu.gmall.product.service.SkuImageService;
import com.atguigu.gmall.product.service.SkuSaleAttrValueService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.atguigu.gmall.product.service.SkuInfoService;
import com.atguigu.gmall.product.mapper.SkuInfoMapper;
import org.redisson.api.RBloomFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 *
 */
@Service
public class SkuInfoServiceImpl extends ServiceImpl<SkuInfoMapper, SkuInfo>
        implements SkuInfoService {
    @Autowired
    private SkuInfoMapper skuInfoMapper;
    @Autowired
    BaseTrademarkMapper baseTrademarkMapper;
    @Autowired
    BaseCategoryViewMapper baseCategoryViewMapper;
    @Autowired
    SkuAttrValueMapper skuAttrValueMapper;
    @Autowired
    private SkuImageService skuImageService;
    @Autowired
    private SkuAttrValueService skuAttrValueService;
    @Autowired
    private SkuSaleAttrValueService skuSaleAttrValueService;
    @Lazy // 延迟加载
    @Qualifier("skuIdBloom")
    @Autowired(required = false) // 若不注入则不报错
    private RBloomFilter<Object> skuIdBloom;
    @Autowired
    RedisTemplate<String, String> redisTemplate;
    //延迟双删线程池
    ScheduledExecutorService delayDeletePool = Executors.newScheduledThreadPool(5);
    @Autowired
    ThreadPoolExecutor coreThreadPool;
    @Autowired
    ListFeignClient listFeignClient;

    @Transactional
    @Override
    public void saveSkuInfo(SkuInfo skuInfo) {
        skuInfoMapper.insert(skuInfo);
        Long skuId = skuInfo.getId();
        //新增时异步给布隆过滤器添加skuId
        skuIdBloom.add(skuId);
        List<SkuImage> skuImageList = skuInfo.getSkuImageList();
        for (SkuImage skuImage : skuImageList) {
            skuImage.setSkuId(skuId);
            skuImageService.save(skuImage);
        }
        List<SkuAttrValue> skuAttrValueList = skuInfo.getSkuAttrValueList();
        for (SkuAttrValue skuAttrValue : skuAttrValueList) {
            skuAttrValue.setSkuId(skuId);
            skuAttrValueService.save(skuAttrValue);
        }
        List<SkuSaleAttrValue> skuSaleAttrValueList = skuInfo.getSkuSaleAttrValueList();
        for (SkuSaleAttrValue skuSaleAttrValue : skuSaleAttrValueList) {
            skuSaleAttrValue.setSkuId(skuId);
            skuSaleAttrValue.setSpuId(skuInfo.getSpuId());
            skuSaleAttrValueService.save(skuSaleAttrValue);
        }
        //保证缓存和数据库的数据一致性,延时双删10s
        deleteCache(skuId);
    }

    //延时双删10s
    private void deleteCache(Long skuId) {
        String cacheKey = RedisConstant.SKU_DETAIL_PREFIX + skuId;
        redisTemplate.delete(cacheKey);
        //线程池延时双删
        delayDeletePool.schedule(() -> {
            redisTemplate.delete(cacheKey);
        }, 10, TimeUnit.SECONDS);
    }

    //上下架
    @Override
    public void onOrOffSale(Long skuId, Integer status) {
        skuInfoMapper.updateStatus(skuId, status);
        if (status == 1) {
            //上架时异步给elasticsearch添数据
            coreThreadPool.execute(() -> {
                saveGoodsToEs(skuId);
            });
        }
        if (status == 0) {
            //下架时异步从elasticsearch删除数据
            coreThreadPool.execute(() -> {
                listFeignClient.deleteGoods(skuId);
            });
        }
    }

    @Override
    public void saveGoodsToEs(Long skuId) {
        Goods goods = new Goods();
        SkuInfo skuInfo = skuInfoMapper.selectById(skuId);
        goods.setId(skuId);
        goods.setDefaultImg(skuInfo.getSkuDefaultImg());
        goods.setTitle(skuInfo.getSkuName());
        goods.setPrice(skuInfo.getPrice().doubleValue());
        goods.setCreateTime(new Date());
        goods.setTmId(skuInfo.getTmId());
        BaseTrademark baseTrademark = baseTrademarkMapper.selectById(skuInfo.getTmId());
        goods.setTmName(baseTrademark.getTmName());
        goods.setTmLogoUrl(baseTrademark.getLogoUrl());
        //自己定义的分类视图
        QueryWrapper<BaseCategoryView> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("category3_id", skuInfo.getCategory3Id());
        BaseCategoryView baseCategoryView = baseCategoryViewMapper.selectOne(queryWrapper);
        goods.setCategory1Id(baseCategoryView.getCategory1Id());
        goods.setCategory1Name(baseCategoryView.getCategory1Name());
        goods.setCategory2Id(baseCategoryView.getCategory2Id());
        goods.setCategory2Name(baseCategoryView.getCategory2Name());
        goods.setCategory3Id(skuInfo.getCategory3Id());
        goods.setCategory3Name(baseCategoryView.getCategory3Name());
        goods.setHotScore(0L);
        //List<SearchAttr>
        List<SearchAttr> searchAttrs = skuAttrValueMapper.getSearchAttrsBySkuId(skuId);
        goods.setAttrs(searchAttrs);
        //远程调用list服务，添加商品到es
        listFeignClient.saveGoods(goods);
    }

    @Override
    public BigDecimal getSalePrice(Long skuId) {

        return skuInfoMapper.getSalePrice(skuId);
    }

    @Override
    public SkuInfo getDetailById(Long skuId) {
        SkuInfo skuInfo = skuInfoMapper.selectById(skuId);
        skuInfo.setSkuImageList(skuImageService.list(new QueryWrapper<SkuImage>().eq("sku_id", skuId)));
        return skuInfo;
    }

    @Override
    public String getValueJson(Long skuId) {
        List<ValueJsonDto> valueJsonDtos = skuInfoMapper.getValueJson(skuId);
        Map<String, String> map = new HashMap<>();
        for (ValueJsonDto valueJsonDto : valueJsonDtos) {
            map.put(valueJsonDto.getValueJson(), valueJsonDto.getSkuId().toString());
        }
        return JsonUtil.toStr(map);
    }

    @Override
    public List<Long> getSkuIds() {
        return skuInfoMapper.getSkuIds();
    }
}




